package cn.bugstack.mybatis.executor;

import cn.bugstack.mybatis.mapping.BoundSql;
import cn.bugstack.mybatis.mapping.MappedStatement;
import cn.bugstack.mybatis.session.Configuration;
import cn.bugstack.mybatis.session.ResultHandler;
import cn.bugstack.mybatis.session.RowBounds;
import cn.bugstack.mybatis.transaction.Transaction;

import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

public abstract class BaseExecutor implements Executor{

    protected Configuration configuration;

    protected Transaction transaction;


    protected boolean closed;

    public BaseExecutor(Configuration configuration, Transaction transaction, boolean closed) {
        this.configuration = configuration;
        this.transaction = transaction;
        this.closed = closed;
    }

    @Override
    public Transaction getTransaction() {
        if (closed) {
            throw new RuntimeException("Executor was closed.");
        }
        return transaction;
    }

    @Override
    public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws Exception {
        if (closed) {
            throw new RuntimeException("Executor was closed.");
        }
        return doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
    }

    protected abstract <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws Exception;

    @Override
    public int update(MappedStatement ms, Object parameter) throws Exception {
        if (closed) {
            throw new RuntimeException("Executor was closed.");
        }
        return doUpdate(ms,parameter);
    }

    protected abstract int doUpdate(MappedStatement ms, Object parameter) throws Exception;


    protected void closeStatement(Statement statement) {
        try {
            statement.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

    }
}
